using System;
using System.Xml;
using System.Data;
using MyClever.Lib;

namespace MyClever.DefaultPlugins
{
    public class ReadAtomFeed : MissionPlugin
    {
        [Package(Direction.Input, "Defines the atom feeds you like to subscribe for.")]
        enum URLInfo
        {
            [Column(typeof(Int32), "Numbers of feeds to store.",
                DefaultValue= "200")]
            NumFeedItems,
            [Column(typeof(string), "URL where you get the rss-feed from.", 
                Validation = "IsURL")]
            URL
        }

        [Package(Direction.Output, "Defines the content of the expected atom feeds.")]
        enum AtomEntries
        {
            [Column(typeof(string), "Identifies the entry using a universally unique and permanent URI.")]
            ID,
            [Column(typeof(string), "Contains a human readable title for the entry.")]
            Title,
            [Column(typeof(string), "Indicates the last time the entry was modified in a significant way.")]
            Updated,
            [Column(typeof(string), "Contains the time of the initial creation or first availability of the entry.")]
            Published,
            [Column(typeof(string), "Conveys a short summary, abstract, or excerpt of an entry.")]
            Summary,
            [Column(typeof(string), "Is the media type of the content.")]
            Content_Type,
            [Column(typeof(string), "Contains a single link relationship type.")]
            Link_Rel,
            [Column(typeof(string), "Human readable information about the link.")]
            Link_Title,
            [Column(typeof(string), "The URI of the referenced resource.")]
            Link_HREF,
            [Column(typeof(string), "Indicates the media type of the resource.")]
            Link_Type,
            [Column(typeof(string), "The length of the resource, in bytes.")]
            Link_Length
        }

        [Plugin(PluginDevStatus.Production, "Fetch the subscribed atom Feed.")]
        public ReadAtomFeed()
        {
        }

        public override void Initialize()
        {
            
            //This is the first Function called by the host...
            //Put anything needed to start with here first
        }

        public override void Dispose()
        {
            //Put any cleanup code in here for when the program is stopped
        }

        /// <summary>
        /// Generate new Source-content.
        /// </summary>
        protected override void Work()
        {
            DataTableReader urlInfoPackage = this.GetDataReader(typeof(URLInfo));
            while (urlInfoPackage.Read())
            {
                Uri atomURL = new Uri(urlInfoPackage[URLInfo.URL.ToString()].ToString());

                this.AddNewLoggingMessage(typeof(URLInfo), String.Format("read feed: {0}", atomURL.AbsoluteUri));

                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(atomURL.AbsoluteUri);

                // work with the atom feed namespace
                XmlNamespaceManager xmlnsManager = new XmlNamespaceManager(xmlDoc.NameTable);
                xmlnsManager.AddNamespace("atom", "http://www.w3.org/2005/Atom");

                XmlNodeList atomNodeItems = xmlDoc.SelectNodes("atom:feed/atom:entry", xmlnsManager);
                
                int numFeeds = 0;
                foreach (XmlNode atomNodeItemOn in atomNodeItems)
                {
                    if (numFeeds < Convert.ToInt32(urlInfoPackage[URLInfo.NumFeedItems.ToString()]))
                    {
                        DataRow newRow = this.CreateNewRowFromPackage(typeof(AtomEntries));

                        foreach (string atomFeedElementOn in Enum.GetNames(typeof(AtomEntries)))
                        {
                            string nodeName = atomFeedElementOn;
                            string attributeName = String.Empty;

                            int underScore = nodeName.IndexOf('_');
                            if (underScore > 0)
                            {
                                nodeName = atomFeedElementOn.Substring(0, underScore);
                                attributeName = atomFeedElementOn.Substring(underScore + 1);
                            }

                            XmlNode atomSubNode = atomNodeItemOn.SelectSingleNode("atom:" + nodeName.ToLower(), xmlnsManager);
                            if (atomSubNode != null)
                            {
                                newRow[atomFeedElementOn] = atomSubNode.InnerText;
                                if (String.Empty != attributeName && null != atomSubNode.Attributes[attributeName.ToLower()])
                                {
                                    newRow[atomFeedElementOn] = atomSubNode.Attributes[attributeName.ToLower()].Value;                    
                                }
                            }
                        }

                        this.AddNewRowToPackage(typeof(AtomEntries), newRow);
                        numFeeds++;
                    }
                }
            }  
        }
    }
}
